Skip to content

Conversation

@joboet
Copy link
Member

@joboet joboet commented Jan 17, 2025

fixes #132442

std specializes on Copy to optimize certain library functions such as clone_from_slice. This is unsound, however, as the Copy implementation may not be always applicable because of lifetime bounds, which specialization does not take into account; the result being that values are copied even though they are not Copy. For instance, this code:

struct SometimesCopy<'a>(&'a Cell<bool>);

impl<'a> Clone for SometimesCopy<'a> {
    fn clone(&self) -> Self {
        self.0.set(true);
        Self(self.0)
    }
}

impl Copy for SometimesCopy<'static> {}

let clone_called = Cell::new(false);
// As SometimesCopy<'clone_called> is not 'static, this must run `clone`,
// setting the value to `true`.
let _ = [SometimesCopy(&clone_called)].clone();
assert!(clone_called.get());

should not panic, but does (playground).

To solve this, this PR introduces a new unsafe trait: TrivialClone. This trait may be implemented whenever the Clone implementation is equivalent to copying the value (so e.g. fn clone(&self) -> Self { *self }). Because of lifetime erasure, there is no way for the Clone implementation to observe lifetime bounds, meaning that even if the TrivialClone has stricter bounds than the Clone implementation, its invariant still holds. Therefore, it is sound to specialize on TrivialClone.

I've changed all Copy specializations in the standard library to specialize on TrivialClone instead. Unfortunately, the unsound #[rustc_unsafe_specialization_marker] attribute on Copy cannot be removed in this PR as hashbrown still depends on it. I'll make a PR updating hashbrown once this lands.

With Copy no longer being considered for specialization, this change alone would result in the standard library optimizations not being applied for user types unaware of TrivialClone. To avoid this and restore the optimizations in most cases, I have changed the expansion of #[derive(Clone)]: Currently, whenever both Clone and Copy are derived, the clone method performs a copy of the value. With this PR, the derive macro also adds a TrivialClone implementation to make this case observable using specialization. I anticipate that most users will use #[derive(Clone, Copy)] whenever both are applicable, so most users will still profit from the library optimizations.

Unfortunately, Hyrum's law applies to this PR: there are some popular crates which rely on the precise specialization behaviour of core to implement "specialization at home", e.g. libAFL. I have no remorse for breaking such horrible code, but perhaps we should open other, better ways to satisfy their needs – for example by dropping the 'static bound on TypeId::of...

@rustbot
Copy link
Collaborator

rustbot commented Jan 17, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jan 17, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jan 17, 2025

Changes to the code generated for builtin derived traits.

cc @nnethercote

@Mark-Simulacrum Mark-Simulacrum added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. I-libs-api-nominated Nominated for discussion during a libs-api team meeting. I-libs-nominated Nominated for discussion during a libs team meeting. labels Jan 17, 2025
@rust-log-analyzer

This comment has been minimized.

@Mark-Simulacrum
Copy link
Member

Going to nominate for libs-api (and libs) since this is both a breaking change (allowed since fixing soundness). I feel like I recall an RFC or some other discussion about us explicitly saying libraries shouldn't do the unsound thing here, but I don't know what that was. https://rust-lang.github.io/rfcs/1521-copy-clone-semantics.html is a bit related but not directly :)

@the8472
Copy link
Member

the8472 commented Jan 17, 2025

RFC 1521 could be interpreted so. Since it requires that Clone is equivalent to Copy when both are implemented.

Since SometimesCopy implements both (at least sometimes) they must be equivalent. And since cannot tell 'static and non-'static apart they must always be equivalent. Therefore the Clone implementation is wrong.


This is unsound, however, as the Copy implementation may not be always applicable because of lifetime bounds, which specialization does not take into account; the result being that values are copied even though they are not Copy.

I still don't think this is unsound in itself. So far all demonstrations of unsoundness required some other unsafe code to turn this into a miscompilation. E.g. the WeirdCow in #132442 or the TrustedLen impl in #89948 both require unsafe to exploit this.

Noratrieb also argues that lifetime-conditional Copy currently is unsupported in MIR.

So ISTM that this could be a documentation shortcoming and a compiler/lang issue that such implementations should be prevented but aren't.

That said, I agree that the current situation is brittle.

@scottmcm
Copy link
Member

Without saying anything about specialization on Copy, there's definitely been past land discussion of splitting the "memcpyable" part of Clone from the "don't need to write .clone()" part. Something like TrivialClone would probably be what that would need as well, and would -- as you mention in the docs in the PR -- be nice for allowing memcpying of non-Copy types like legacy::Range.

But that gets back to needing, as the8472 said, a way to actually block lifetime-bad implementations before it could be stable.

@Amanieu Amanieu removed I-libs-api-nominated Nominated for discussion during a libs-api team meeting. I-libs-nominated Nominated for discussion during a libs team meeting. labels Jan 21, 2025
@the8472
Copy link
Member

the8472 commented Jan 21, 2025

We discussed this during today's libs-API meeting. We currently are not aware of any safe code that is unsound due to these specializations and there were concerns about performance regressions for user types that manually implement Copy.

So we're leaning towards keeping the implementations as they are and instead improving things in other ways such as adding compiler warnings or improving the Copy documentation or unsafe-code-guidelines.


We'd like input from T-types whether they agree with this assessment and if something should be changed on the language side, e.g. by forbidding or at least warning on lifetime-conditional implementations, similar to how Drop impls must have the same bounds as the type it's implemented on.

A compiler-team member has indicated that lifetime-dependent Copy impls are de-facto unsupported.

@the8472 the8472 added the I-types-nominated Nominated for discussion during a types team meeting. label Jan 21, 2025
@BoxyUwU
Copy link
Member

BoxyUwU commented Jan 21, 2025

Forbidding lifetime dependent copy impls seems like it would be rather breaking (but that's pure speculation, we ought to do a crater run to check if anyone feels strongly we should forbid such impls), though generally I don't feel great about forbidding lifetime dependent copy impls. I also don't think a warning on lifetime dependent copy impls really helps anything for std as warnings cannot be relied upon for soundness and so std's usage of specialization would still be wrong.

In general I would prefer std to not be using specialization in any ways that affect behaviour in any way, it's stably exposing unstable broken parts of the type system in ways that are arguably unsound (allows you to prove trait bounds hold when they do not).

imo what should have happened is that years ago when specialization was found to be unsound all these specializations should have been ripped out regardless of the performance cost and re-added with a PR like this that respects lifetime constraints and treats the unsafe specialization marker attr as something unsafe with invariants to be upheld.

I cant speak for the whole types team but that's atleast my opinion as a types member 🤷‍♀️


On a semi-related note, does std still specialize fused iterator stuff in ways that exposes specialization to stable too? I remember that being a thing some years ago but haven't kept up to date with how std is using specialization

@the8472
Copy link
Member

the8472 commented Jan 21, 2025

On a semi-related note, does std still specialize fused iterator stuff in ways that exposes specialization to stable too?

Yes, but #86765 changed the specialization so that incorrect specializations only result in correctness issues and not soundness ones.

And we have TrusedFused now for cases where it's relevant to soundness.

@lcnr
Copy link
Contributor

lcnr commented Jan 28, 2025

The types team discussed this on zulip: https://rust-lang.zulipchat.com/#narrow/channel/326866-t-types.2Fnominated/topic/.23135634.3A.20stop.20specializing.20on.20.60Copy.60

My opinion/summary from there:

  • rn specializing on Copy is unsound from a type system pov, even as I don't know of, and can't think of, actual cases whether this results in broken invariants/ub
    • fixing specialization with lifetime dependent impls to be sound won't happen in the near future
    • forbidding lifetime dependent Copy impls is not possible/too much of a breaking change, as they are currently allowed with arbitrary where-bounds

I would like to avoid specializing on Copy. I believe we should land this PR if the approach of having a new trait implemented on derive(Copy) is good enough perf wise (whatever that means)

@lcnr lcnr removed the I-types-nominated Nominated for discussion during a types team meeting. label Jan 28, 2025
@bors
Copy link
Collaborator

bors commented Feb 2, 2025

☔ The latest upstream changes (presumably #136448) made this pull request unmergeable. Please resolve the merge conflicts.

@joboet joboet added the I-libs-nominated Nominated for discussion during a libs team meeting. label Feb 3, 2025
@cuviper
Copy link
Member

cuviper commented Feb 7, 2025

Should we add manual conditional impls for types like Option<T> and [T; N]?
And how about compiler-implemented types like closures and tuples?

I know we're not going to perfectly recover everything that Copy specialization did right, but I think these will be impactful. It's also great that we could go further, like conditional Range<T> and unconditional slice::Iter<'_, T>.

@rust-log-analyzer

This comment has been minimized.

@joboet
Copy link
Member Author

joboet commented Feb 11, 2025

Should we add manual conditional impls for types like Option<T> and [T; N]? And how about compiler-implemented types like closures and tuples?

I know we're not going to perfectly recover everything that Copy specialization did right, but I think these will be impactful. It's also great that we could go further, like conditional Range<T> and unconditional slice::Iter<'_, T>.

Maybe, but let's just try the performance of this first:
@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (055d0d6): comparison URL.

Overall result: ❌✅ regressions and improvements - please read the text below

Our benchmarks found a performance regression caused by this PR.
This might be an actual regression, but it can also be just noise.

Next Steps:

  • If the regression was expected or you think it can be justified,
    please write a comment with sufficient written justification, and add
    @rustbot label: +perf-regression-triaged to it, to mark the regression as triaged.
  • If you think that you know of a way to resolve the regression, try to create
    a new PR with a fix for the regression.
  • If you do not understand the regression or you think that it is just noise,
    you can ask the @rust-lang/wg-compiler-performance working group for help (members of this group
    were already notified of this PR).

@rustbot label: +perf-regression
cc @rust-lang/wg-compiler-performance

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.7% [0.1%, 3.2%] 110
Regressions ❌
(secondary)
0.8% [0.1%, 1.8%] 50
Improvements ✅
(primary)
-0.9% [-1.4%, -0.5%] 2
Improvements ✅
(secondary)
-0.4% [-0.5%, -0.1%] 7
All ❌✅ (primary) 0.7% [-1.4%, 3.2%] 112

Max RSS (memory usage)

Results (primary 1.0%, secondary -0.0%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.7% [0.6%, 4.0%] 7
Regressions ❌
(secondary)
1.3% [1.3%, 1.3%] 1
Improvements ✅
(primary)
-1.4% [-2.1%, -0.8%] 2
Improvements ✅
(secondary)
-1.4% [-1.4%, -1.4%] 1
All ❌✅ (primary) 1.0% [-2.1%, 4.0%] 9

Cycles

Results (primary 3.7%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
3.7% [2.2%, 4.6%] 10
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 3.7% [2.2%, 4.6%] 10

Binary size

Results (primary 0.3%, secondary 0.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
0.3% [0.0%, 2.1%] 103
Regressions ❌
(secondary)
0.2% [0.0%, 1.4%] 68
Improvements ✅
(primary)
-0.0% [-0.0%, -0.0%] 4
Improvements ✅
(secondary)
-0.0% [-0.0%, -0.0%] 3
All ❌✅ (primary) 0.3% [-0.0%, 2.1%] 107

Bootstrap: 476.631s -> 476.7s (0.01%)
Artifact size: 391.32 MiB -> 391.36 MiB (0.01%)

bors added a commit that referenced this pull request Nov 22, 2025
library: upgrade to hashbrown v0.16.1

This is another step toward unspecializing `Copy`.

See also #135634 and rust-lang/hashbrown#662

r? `@Amanieu`
cc `@joboet`
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
stop specializing on `Copy`

fixes rust-lang#132442

`std` specializes on `Copy` to optimize certain library functions such as `clone_from_slice`. This is unsound, however, as the `Copy` implementation may not be always applicable because of lifetime bounds, which specialization does not take into account; the result being that values are copied even though they are not `Copy`. For instance, this code:
```rust
struct SometimesCopy<'a>(&'a Cell<bool>);

impl<'a> Clone for SometimesCopy<'a> {
    fn clone(&self) -> Self {
        self.0.set(true);
        Self(self.0)
    }
}

impl Copy for SometimesCopy<'static> {}

let clone_called = Cell::new(false);
// As SometimesCopy<'clone_called> is not 'static, this must run `clone`,
// setting the value to `true`.
let _ = [SometimesCopy(&clone_called)].clone();
assert!(clone_called.get());
```
should not panic, but does ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6be7a48cad849d8bd064491616fdb43c)).

To solve this, this PR introduces a new `unsafe` trait: `TrivialClone`. This trait may be implemented whenever the `Clone` implementation is equivalent to copying the value (so e.g. `fn clone(&self) -> Self { *self }`). Because of lifetime erasure, there is no way for the `Clone` implementation to observe lifetime bounds, meaning that even if the `TrivialClone` has stricter bounds than the `Clone` implementation, its invariant still holds. Therefore, it is sound to specialize on `TrivialClone`.

I've changed all `Copy` specializations in the standard library to specialize on `TrivialClone` instead. Unfortunately, the unsound `#[rustc_unsafe_specialization_marker]` attribute on `Copy` cannot be removed in this PR as `hashbrown` still depends on it. I'll make a PR updating `hashbrown` once this lands.

With `Copy` no longer being considered for specialization, this change alone would result in the standard library optimizations not being applied for user types unaware of `TrivialClone`. To avoid this and restore the optimizations in most cases, I have changed the expansion of `#[derive(Clone)]`: Currently, whenever both `Clone` and `Copy` are derived, the `clone` method performs a copy of the value. With this PR, the derive macro also adds a `TrivialClone` implementation to make this case observable using specialization. I anticipate that most users will use `#[derive(Clone, Copy)]` whenever both are applicable, so most users will still profit from the library optimizations.

Unfortunately, Hyrum's law applies to this PR: there are some popular crates which rely on the precise specialization behaviour of `core` to implement "specialization at home", e.g. [`libAFL`](https://github.com/AFLplusplus/LibAFL/blob/89cff637025c1652c24e8d97a30a2e3d01f187a4/libafl_bolts/src/tuples.rs#L27-L49). I have no remorse for breaking such horrible code, but perhaps we should open other, better ways to satisfy their needs – for example by dropping the `'static` bound on `TypeId::of`...
theemathas added a commit to theemathas/rust that referenced this pull request Dec 10, 2025
These `TrivialClone` impls previously had `?Sized` bounds, which are
different from the `PointeeSized` bounds on the corresponding
`Clone` and `Copy` impls. So, I've changed the `?Sized` bounds into
`PointeeSized` bounds.

This mistake was made presumably because the `TrivialClone` PR
(rust-lang#135634) was opened in Jan 2025,
but merged in Nov 2025. During that time, the sized hierachy PR
(rust-lang#137944) was opened in Mar 2025,
and merged in Jun 2025. The `TrivialClone` PR was not updated to account
for the sized hierachy changes.
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
stop specializing on `Copy`

fixes rust-lang#132442

`std` specializes on `Copy` to optimize certain library functions such as `clone_from_slice`. This is unsound, however, as the `Copy` implementation may not be always applicable because of lifetime bounds, which specialization does not take into account; the result being that values are copied even though they are not `Copy`. For instance, this code:
```rust
struct SometimesCopy<'a>(&'a Cell<bool>);

impl<'a> Clone for SometimesCopy<'a> {
    fn clone(&self) -> Self {
        self.0.set(true);
        Self(self.0)
    }
}

impl Copy for SometimesCopy<'static> {}

let clone_called = Cell::new(false);
// As SometimesCopy<'clone_called> is not 'static, this must run `clone`,
// setting the value to `true`.
let _ = [SometimesCopy(&clone_called)].clone();
assert!(clone_called.get());
```
should not panic, but does ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6be7a48cad849d8bd064491616fdb43c)).

To solve this, this PR introduces a new `unsafe` trait: `TrivialClone`. This trait may be implemented whenever the `Clone` implementation is equivalent to copying the value (so e.g. `fn clone(&self) -> Self { *self }`). Because of lifetime erasure, there is no way for the `Clone` implementation to observe lifetime bounds, meaning that even if the `TrivialClone` has stricter bounds than the `Clone` implementation, its invariant still holds. Therefore, it is sound to specialize on `TrivialClone`.

I've changed all `Copy` specializations in the standard library to specialize on `TrivialClone` instead. Unfortunately, the unsound `#[rustc_unsafe_specialization_marker]` attribute on `Copy` cannot be removed in this PR as `hashbrown` still depends on it. I'll make a PR updating `hashbrown` once this lands.

With `Copy` no longer being considered for specialization, this change alone would result in the standard library optimizations not being applied for user types unaware of `TrivialClone`. To avoid this and restore the optimizations in most cases, I have changed the expansion of `#[derive(Clone)]`: Currently, whenever both `Clone` and `Copy` are derived, the `clone` method performs a copy of the value. With this PR, the derive macro also adds a `TrivialClone` implementation to make this case observable using specialization. I anticipate that most users will use `#[derive(Clone, Copy)]` whenever both are applicable, so most users will still profit from the library optimizations.

Unfortunately, Hyrum's law applies to this PR: there are some popular crates which rely on the precise specialization behaviour of `core` to implement "specialization at home", e.g. [`libAFL`](https://github.com/AFLplusplus/LibAFL/blob/89cff637025c1652c24e8d97a30a2e3d01f187a4/libafl_bolts/src/tuples.rs#L27-L49). I have no remorse for breaking such horrible code, but perhaps we should open other, better ways to satisfy their needs – for example by dropping the `'static` bound on `TypeId::of`...
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Dec 10, 2025
…ized, r=joboet

Use `PointeeSized` bound for `TrivialClone` impls

These `TrivialClone` impls previously had `?Sized` bounds, which are different from the `PointeeSized` bounds on the corresponding `Clone` and `Copy` impls. So, I've changed the `?Sized` bounds into `PointeeSized` bounds.

This mistake was made presumably because the `TrivialClone` PR (rust-lang#135634) was opened in Jan 2025, but merged in Nov 2025. During that time, the sized hierachy PR (rust-lang#137944) was opened in Mar 2025, and merged in Jun 2025. The `TrivialClone` PR was not updated to account for the sized hierachy changes.

r? `@joboet`
rust-timer added a commit that referenced this pull request Dec 10, 2025
Rollup merge of #149839 - theemathas:trivial-clone-pointee-sized, r=joboet

Use `PointeeSized` bound for `TrivialClone` impls

These `TrivialClone` impls previously had `?Sized` bounds, which are different from the `PointeeSized` bounds on the corresponding `Clone` and `Copy` impls. So, I've changed the `?Sized` bounds into `PointeeSized` bounds.

This mistake was made presumably because the `TrivialClone` PR (#135634) was opened in Jan 2025, but merged in Nov 2025. During that time, the sized hierachy PR (#137944) was opened in Mar 2025, and merged in Jun 2025. The `TrivialClone` PR was not updated to account for the sized hierachy changes.

r? `@joboet`
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
…oboet

Use `PointeeSized` bound for `TrivialClone` impls

These `TrivialClone` impls previously had `?Sized` bounds, which are different from the `PointeeSized` bounds on the corresponding `Clone` and `Copy` impls. So, I've changed the `?Sized` bounds into `PointeeSized` bounds.

This mistake was made presumably because the `TrivialClone` PR (rust-lang/rust#135634) was opened in Jan 2025, but merged in Nov 2025. During that time, the sized hierachy PR (rust-lang/rust#137944) was opened in Mar 2025, and merged in Jun 2025. The `TrivialClone` PR was not updated to account for the sized hierachy changes.

r? `@joboet`
rust-bors bot pushed a commit that referenced this pull request Jan 13, 2026
See also #135634, #149159, and rust-lang/hashbrown#662.

This includes an in-tree upgrade of `indexmap` as well, which uses the
new `HashTable` buckets API internally, hopefully impacting performance
for the better!
github-actions bot pushed a commit to model-checking/verify-rust-std that referenced this pull request Jan 17, 2026
…Amanieu

library: upgrade to hashbrown v0.16.1

This is another step toward unspecializing `Copy`.

See also rust-lang#135634 and rust-lang/hashbrown#662

r? `@Amanieu`
cc `@joboet`
rust-bors bot pushed a commit that referenced this pull request Jan 20, 2026
compiler: upgrade to hashbrown 0.16.1

See also #135634, #149159, and rust-lang/hashbrown#662.

This includes an in-tree upgrade of `indexmap` as well, which uses the
new `HashTable` buckets API internally, hopefully impacting performance
for the better.

And finally, we can remove `#[rustc_unsafe_specialization_marker]` on `Copy`!

cc @joboet
r? @Amanieu
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jan 21, 2026
compiler: upgrade to hashbrown 0.16.1

See also rust-lang/rust#135634, rust-lang/rust#149159, and rust-lang/hashbrown#662.

This includes an in-tree upgrade of `indexmap` as well, which uses the
new `HashTable` buckets API internally, hopefully impacting performance
for the better.

And finally, we can remove `#[rustc_unsafe_specialization_marker]` on `Copy`!

cc @joboet
r? @Amanieu
github-actions bot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Jan 22, 2026
compiler: upgrade to hashbrown 0.16.1

See also rust-lang/rust#135634, rust-lang/rust#149159, and rust-lang/hashbrown#662.

This includes an in-tree upgrade of `indexmap` as well, which uses the
new `HashTable` buckets API internally, hopefully impacting performance
for the better.

And finally, we can remove `#[rustc_unsafe_specialization_marker]` on `Copy`!

cc @joboet
r? @Amanieu
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Jan 23, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [rust](https://github.com/rust-lang/rust) | minor | `1.92.0` → `1.93.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>rust-lang/rust (rust)</summary>

### [`v1.93.0`](https://github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1930-2026-01-22)

[Compare Source](rust-lang/rust@1.92.0...1.93.0)

\==========================

<a id="1.93.0-Language"></a>

## Language

- [Stabilize several s390x `vector`-related target features and the `is_s390x_feature_detected!` macro](rust-lang/rust#145656)
- [Stabilize declaration of C-style variadic functions for the `system` ABI](rust-lang/rust#145954)
- [Emit error when using some keyword as a `cfg` predicate](rust-lang/rust#146978)
- [Stabilize `asm_cfg`](rust-lang/rust#147736)
- [During const-evaluation, support copying pointers byte-by-byte](rust-lang/rust#148259)
- [LUB coercions now correctly handle function item types, and functions with differing safeties](rust-lang/rust#148602)
- [Allow `const` items that contain mutable references to `static` (which is *very* unsafe, but not *always* UB)](rust-lang/rust#148746)
- [Add warn-by-default `const_item_interior_mutations` lint to warn against calls which mutate interior mutable `const` items](rust-lang/rust#148407)
- [Add warn-by-default `function_casts_as_integer` lint](rust-lang/rust#141470)

<a id="1.93.0-Compiler"></a>

## Compiler

- [Stabilize `-Cjump-tables=bool`](rust-lang/rust#145974). The flag was previously called `-Zno-jump-tables`.

<a id="1.93.0-Platform-Support"></a>

## Platform Support

- [Promote `riscv64a23-unknown-linux-gnu` to Tier 2 (without host tools)](rust-lang/rust#148435)

Refer to Rust's [platform support page][platform-support-doc]
for more information on Rust's tiered platform support.

[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html

<a id="1.93.0-Libraries"></a>

## Libraries

- [Stop internally using `specialization` on the `Copy` trait as it is unsound in the presence of lifetime dependent `Copy` implementations. This may result in some performance regressions as some standard library APIs may now call `Clone::clone` instead of performing bitwise copies](rust-lang/rust#135634)
- [Allow the global allocator to use thread-local storage and `std::thread::current()`](rust-lang/rust#144465)
- [Make `BTree::append` not update existing keys when appending an entry which already exists](rust-lang/rust#145628)
- [Don't require `T: RefUnwindSafe` for `vec::IntoIter<T>: UnwindSafe`](rust-lang/rust#145665)

<a id="1.93.0-Stabilized-APIs"></a>

## Stabilized APIs

- [`<[MaybeUninit<T>]>::assume_init_drop`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.assume_init_drop)
- [`<[MaybeUninit<T>]>::assume_init_ref`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.assume_init_ref)
- [`<[MaybeUninit<T>]>::assume_init_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.assume_init_mut)
- [`<[MaybeUninit<T>]>::write_copy_of_slice`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.write_copy_of_slice)
- [`<[MaybeUninit<T>]>::write_clone_of_slice`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.write_clone_of_slice)
- [`String::into_raw_parts`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_raw_parts)
- [`Vec::into_raw_parts`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.into_raw_parts)
- [`<iN>::unchecked_neg`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unchecked_neg)
- [`<iN>::unchecked_shl`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unchecked_shl)
- [`<iN>::unchecked_shr`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unchecked_shr)
- [`<uN>::unchecked_shl`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unchecked_shl)
- [`<uN>::unchecked_shr`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unchecked_shr)
- [`<[T]>::as_array`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_array)
- [`<[T]>::as_array_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_mut_array)
- [`<*const [T]>::as_array`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_array)
- [`<*mut [T]>::as_array_mut`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_mut_array)
- [`VecDeque::pop_front_if`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.pop_front_if)
- [`VecDeque::pop_back_if`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.pop_back_if)
- [`Duration::from_nanos_u128`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_nanos_u128)
- [`char::MAX_LEN_UTF8`](https://doc.rust-lang.org/stable/std/primitive.char.html#associatedconstant.MAX_LEN_UTF8)
- [`char::MAX_LEN_UTF16`](https://doc.rust-lang.org/stable/std/primitive.char.html#associatedconstant.MAX_LEN_UTF16)
- [`std::fmt::from_fn`](https://doc.rust-lang.org/stable/std/fmt/fn.from_fn.html)
- [`std::fmt::FromFn`](https://doc.rust-lang.org/stable/std/fmt/struct.FromFn.html)

<a id="1.93.0-Cargo"></a>

## Cargo

- [Enable CARGO\_CFG\_DEBUG\_ASSERTIONS in build scripts based on profile](rust-lang/cargo#16160)
- [In `cargo tree`, support long forms for `--format` variables](rust-lang/cargo#16204)
- [Add `--workspace` to `cargo clean`](rust-lang/cargo#16263)

<a id="1.93.0-Rustdoc"></a>

## Rustdoc

- [Remove `#![doc(document_private_items)]`](rust-lang/rust#146495)
- [Include attribute and derive macros in search filters for "macros"](rust-lang/rust#148176)
- [Include extern crates in search filters for `import`](rust-lang/rust#148301)
- [Validate usage of crate-level doc attributes](rust-lang/rust#149197).  This means if any of `html_favicon_url`, `html_logo_url`, `html_playground_url`, `issue_tracker_base_url`, or `html_no_source` either has a missing value, an unexpected value, or a value of the wrong type, rustdoc will emit the deny-by-default lint `rustdoc::invalid_doc_attributes`.

<a id="1.93.0-Compatibility-Notes"></a>

## Compatibility Notes

- [Introduce `pin_v2` into the builtin attributes namespace](rust-lang/rust#139751)
- [Update bundled musl to 1.2.5](rust-lang/rust#142682)
- [On Emscripten, the unwinding ABI used when compiling with `panic=unwind` was changed from the JS exception handling ABI to the wasm exception handling ABI.](rust-lang/rust#147224) If linking C/C++ object files with Rust objects, `-fwasm-exceptions` must be passed to the linker now. On nightly Rust, it is possible to get the old behavior with `-Zwasm-emscripten-eh=false -Zbuild-std`, but it will be removed in a future release.
- The `#[test]` attribute, used to define tests, was previously ignored in various places where it had no meaning (e.g on trait methods or types). Putting the `#[test]` attribute in these places is no longer ignored, and will now result in an error; this may also result in errors when generating rustdoc. [Error when `test` attribute is applied to structs](rust-lang/rust#147841)
- Cargo now sets the `CARGO_CFG_DEBUG_ASSERTIONS` environment variable in more situations. This will cause crates depending on `static-init` versions 1.0.1 to 1.0.3 to fail compilation with "failed to resolve: use of unresolved module or unlinked crate `parking_lot`". See [the linked issue](rust-lang/rust#150646 (comment)) for details.
- [User written types in the `offset_of!` macro are now checked to be well formed.](rust-lang/rust#150465)
- `cargo publish` no longer emits `.crate` files as a final artifact for user access when the `build.build-dir` config is unset
- [Upgrade the `deref_nullptr` lint from warn-by-default to deny-by-default](rust-lang/rust#148122)
- [Add future-incompatibility warning for `...` function parameters without a pattern outside of `extern` blocks](rust-lang/rust#143619)
- [Introduce future-compatibility warning for `repr(C)` enums whose discriminant values do not fit into a `c_int` or `c_uint`](rust-lang/rust#147017)
- [Introduce future-compatibility warning against ignoring `repr(C)` types as part of `repr(transparent)`](rust-lang/rust#147185)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi44OC4yIiwidXBkYXRlZEluVmVyIjoiNDIuODguMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array and Vec's Clone specialization is maybe unsound with conditionally Copy types.